using System;
using System.Diagnostics;
using System.Text;

namespace Mindless
{
    /// <summary>
    /// A game of cards.
    /// </summary>
    public class Game
    {
        /// <summary>
        /// Creates a new game. All teams have a score of 0.
        /// </summary>
        public Game()
        {
            this.scores = new int[Settings.TeamCount];
            this.save = new int[this.scores.Length];
            this.isOver = false;
        }

        /// <summary>
        /// Creates a copy of the given game.
        /// </summary>
        public Game(Game game)
        {
            this.scores = (int[]) game.scores.Clone();
            this.save = (int[]) game.save.Clone();
            this.isOver = game.isOver;
        }

        /// <summary>
        /// String representation of the receiver, suitable for display.
        /// </summary>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("[");
            bool isFirst = true;
            foreach (int score in this.scores)
            {
                if (isFirst)
                    isFirst = false;
                else
                    sb.Append(", ");
                sb.Append(score);
            }
            sb.Append("]");

            return sb.ToString();
        }

        /// <summary>
        /// Adds the given team scores to the receiver's team scores. This can be reversed via
        /// Pop().
        /// </summary>
        public void Push(int[] scores)
        {
            Debug.Assert(!this.isOver);
            Debug.Assert(scores.Length == this.scores.Length);

                // save the current score of the game
            this.scores.CopyTo(this.save, 0);

                // increment each team's score
            int highScore = 0;
            for (int iTeam = 0; iTeam < scores.Length; ++iTeam)
            {
                int score = (this.scores[iTeam] += scores[iTeam]);

                    // if the game is over, determine which team won
                if (score >= Settings.GameThreshold)
                {
                    if (score > highScore)
                    {
                        highScore = score;
                        this.iWinningTeam = iTeam;
                        this.isOver = true;
                    }
                        // tie score? - keep playing
                    else if (score == highScore)
                    {
                        this.iWinningTeam = -1;
                        this.isOver = false;
                    }
                }
            }
        }

        /// <summary>
        /// Restores the receiver to its previous state (before Push() was called).
        /// </summary>
        public void Pop()
        {
            this.save.CopyTo(this.scores, 0);
            this.isOver = false;
            this.iWinningTeam = -1;
        }

        /// <summary>
        /// Each team's score.
        /// </summary>
        public int[] Score
        {
            get { return this.scores; }
        }

        /// <summary>
        /// Is the game over?
        /// </summary>
        public bool IsOver
        {
            get { return this.isOver; }
        }

        /// <summary>
        /// Which team won?
        /// </summary>
        public int WinningTeam
        {
            get { return this.iWinningTeam; }
        }

        protected int[] scores;
        protected int[] save;
        protected bool isOver = false;
        protected int iWinningTeam = -1;
    }
}